/**
* 
* GUI window Explorer 
* Copyright (c) 2009 Ecole Centrale de Nantes IRCCyN  
* Classe: Explorer.java 
* see <a href="{@docRoot}">Trace for more information</a>
* 
* @author: Urunuela Richard
* @version 3.2
*/
package programme.GUI;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.border.Border;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;

import storm.SimulationKernel;
import storm.Data.Data;
import storm.Processors.Processor;
import storm.Schedulers.Scheduler;
import storm.Tasks.Task;

public class Explorer  extends JPanel implements TreeSelectionListener,KeyListener {
	SimulationKernel monKL;
	JTree tree;
	JConsole console;
	 JSplitPane splitPane;
	JPanel panelRight ; // Panel de pub
	GridBagConstraints c;
    JLabel label;
/**
 * 
 */
    public void setRootPanel(){
    	 /*
         * panel de droit 
         */
        panelRight= new JPanel();
        ClassLoader cl = this.getClass().getClassLoader();
        java.net.URL url = cl.getResource("images/icon-s.gif");
        
	    ImageIcon icon = new ImageIcon(url,"");

	    label = new JLabel("", icon, JLabel.LEFT);

	    label.setVerticalTextPosition(JLabel.BOTTOM);
	    label.setHorizontalTextPosition(JLabel.CENTER);
	    GridBagLayout layout =new GridBagLayout() ;
	    panelRight.setLayout(layout);
	    c = new GridBagConstraints();
	    
	    
       c.fill = GridBagConstraints.HORIZONTAL;
	    
	    c.weightx = 0.0;
	    c.gridwidth = 3;
	    c.gridx = 0;
	    c.gridy = 0;

	    
	    panelRight.add(label,c);
	    
	    c.fill = GridBagConstraints.HORIZONTAL;
	    
	    c.weightx = 0.0;
	    c.gridwidth = 3;
	    c.gridx = 0;
	    c.gridy = 1;

	    
	    panelRight.add(new JLabel(" D "+this.monKL.duration) ,c);
	    c.fill = GridBagConstraints.HORIZONTAL;
	    
	    c.weightx = 0.0;
	    c.gridwidth = 3;
	    c.gridx = 0;
	    c.gridy = 2;
	    panelRight.add(new JLabel( " S " +  this.monKL.precision) ,c);
	   
        //

    }
    /**
     * 
     * @param monKL
     * @param console
     */
	public Explorer(SimulationKernel monKL, JConsole console) {
        super(new GridLayout(1,0));
		this.monKL=monKL;
		this.console = console;
        DefaultMutableTreeNode top =
            new DefaultMutableTreeNode("ROOT");
        createNodes(top);
        tree = new JTree(top);
        tree.addKeyListener(this);
        
        tree.addTreeSelectionListener(this);
        
        tree.setCellRenderer(new MyRenderer());
  
        setRootPanel();
       
        JScrollPane treeView = new JScrollPane(tree);
        splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
  

        splitPane.setTopComponent(treeView);
        splitPane.setBottomComponent(panelRight);
        add(splitPane);
        
    	this.addKeyListener(this);

	
	}
	
	/**
	 * 
	 */
	public void valueChanged(TreeSelectionEvent arg0) {
		
		this.panelRight.repaint();
		
		DefaultMutableTreeNode Node = (DefaultMutableTreeNode) arg0.getNewLeadSelectionPath().getLastPathComponent();
		if (Node.isRoot())  {
			setRootPanel();
		
	        splitPane.setBottomComponent(panelRight);

		}
		else {
			panelRight = ((nInterface) Node).getPanel();
			panelRight.setSize(100, 100);
		
			  splitPane.setBottomComponent(panelRight);
			  splitPane.setDividerLocation(0.5);
		}
		
		
	}
	
	
/**
 * create node with liste entities 
 * @param top
 */
	
	
    private void createNodes(DefaultMutableTreeNode top) {
        
        /**
         *Sched
         *
         */
        nScheduler sch = new nScheduler(monKL.getScheduler());
        
        
        top.add(sch);
        /**
         * Task
         */
        ArrayList ltasks= monKL.getTasksListeManager().getALLTask();
        Iterator i = ltasks.iterator();
        while(i.hasNext()){
        	Task T = (Task)i.next();
        	nTask n =new nTask(T);
        
        	top.add(n);
        	
        	
        	
        }
        
        /**
         * Data
         */
        ArrayList lDatas = monKL.getData();
        Iterator i2 = lDatas.iterator();
        while(i2.hasNext()){
        	top.add(new nData((Data)i2.next()));
        	
        	
        }
        /**
         * Processors
         */
        ArrayList lProcessors = monKL.getTasksListeManager().getALLProcessors();
        Iterator i3 = lProcessors.iterator();
        while(i3.hasNext()){
        	top.add(new nProcessor((Processor)i3.next()));
        	
        	
        }
        
    }
    
    /**
     * renderer
     */
    private class MyRenderer extends DefaultTreeCellRenderer {
    	public MyRenderer() {
    		super();
    	}
    	/**
    	 *Red??fini la m??thode getTreeCellRendererComponent 
    	 */

    	public Component getTreeCellRendererComponent(JTree tree, Object value,boolean sel, boolean expanded, 							boolean leaf, int row,boolean hasFocus) {
    		
	ClassLoader cl = this.getClass().getClassLoader();
		    
		    
		    java.net.URL url = cl.getResource("images/clip-art-bullet-black-ball-01.gif");
		     
		    ImageIcon iconRoot = new ImageIcon(url,"");
		    /**
		     * sched
		     */
		    java.net.URL url2 = cl.getResource("images/clip-art-bullet-blue-ball-01.gif");
		    ImageIcon iconSched = new ImageIcon(url2,"");
		    
		    java.net.URL url3 = cl.getResource("images/clip-art-bullet-blue-square-01.gif");
		    ImageIcon iconSchedp = new ImageIcon(url3,"");
		    /**
		     * Data
		     */
		    java.net.URL url6 = cl.getResource("images/clip-art-bullet-yellow-ball-01.gif");
		    ImageIcon iconData = new ImageIcon(url6,"");
		    
		    java.net.URL url7 = cl.getResource("images/clip-art-bullet-yellow-square-01.gif");
		    ImageIcon iconDatap = new ImageIcon(url7,"");
		    /**
		     * Processor
		     */
		    java.net.URL url8 = cl.getResource("images/clip-art-bullet-green-ball-01.gif");
		    ImageIcon iconProcessor = new ImageIcon(url8,"");
		    
		    java.net.URL url9 = cl.getResource("images/clip-art-bullet-green-square-01.gif");
		    ImageIcon iconProcessorp = new ImageIcon(url9,"");
		    /**		    
		     * Task
		     */
		    java.net.URL url4 = cl.getResource("images/clip-art-bullet-red-ball-01.gif");
		    ImageIcon iconTask = new ImageIcon(url4,"");
		    
		    java.net.URL url5 = cl.getResource("images/clip-art-bullet-red-square-01.gif");
		    ImageIcon iconTaskp = new ImageIcon(url5,"");
		    
    		DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;	

    		/**
    		 * Sched
    		 */
    			if (node instanceof nScheduler) {
    				nScheduler S = (nScheduler) node;
    				this.setText(S.getName());
    				
    				if(!sel){
    				    this.setIcon(iconSched);
    					
        				this.setOpenIcon(iconSched);
        				this.setClosedIcon(iconSched);
    				}
    				else{
    					this.setIcon(iconSchedp);
    					this.setOpenIcon(iconSchedp);
        				this.setClosedIcon(iconSchedp);
        				
    				}
    				/**
    				 *Permet de d??finir l'icone pour le type de classe trouv??... 
    				 */

    				
    			}
    			/**
    			 * Task 
    			 */
    			else if (node instanceof TaskActivation) {
    				TaskActivation T = (TaskActivation) node;
    				this.setText(T.getName());
    			}
    			else if (node instanceof nTask) {
    				nTask T = (nTask) node;
    				this.setText(T.getName());
    				

    				if(!sel){
    				    this.setIcon(iconTask);
    					
        				this.setOpenIcon(iconTask);
        				this.setClosedIcon(iconTask);
        			
    				}
    				else{
    					this.setIcon(iconTaskp);
    					this.setOpenIcon(iconTaskp);
        				this.setClosedIcon(iconTaskp);
        				
    				}
    			}
    			/**
    			 * Data
    			 */
    			else if (node instanceof nData) {
    				nData D = (nData) node;
    				this.setText(D.getName());
    				
    				if(!sel){
    				    this.setIcon(iconData);
    					
        				this.setOpenIcon(iconData);
        				this.setClosedIcon(iconData);
    				}
    				else{
    					this.setIcon(iconDatap);
    					this.setOpenIcon(iconDatap);
        				this.setClosedIcon(iconDatap);
        				
    				}
    			}
    			/**
    			 * Processor
    			 */
    			else if (node instanceof nProcessor) {
    				nProcessor D = (nProcessor) node;
    				this.setText(D.getName());
    				
    				if(!sel){
    				    this.setIcon(iconProcessor);
    					
        				this.setOpenIcon(iconProcessor);
        				this.setClosedIcon(iconProcessor);
    				}
    				else{
    					this.setIcon(iconProcessorp);
    					this.setOpenIcon(iconProcessorp);
        				this.setClosedIcon(iconProcessorp);
        				
    				}
    			}
    			else {
    				/**
    				 * ROOT ;) 
    				 */
    			
    				this.setText("ROOT");
   				 this.setIcon(iconRoot);
					
 				this.setOpenIcon(iconRoot);
 				this.setClosedIcon(iconRoot);
    			}
    			


    		return this;
    	}
    }
    /**
     * 
     */
    private interface nInterface {
    	public JPanel getPanel();
    	
    }
    /**
     * Test not implement at all
     * TO DO
     */
    
    
    private class TaskActivation extends DefaultMutableTreeNode implements nInterface{
    	Task task;
    	private JPanel monPanel;
    	private String label;
		public TaskActivation(Task task) {
			// TODO Auto-generated constructor stub
			super();
			this.task=task;
			this.label = "Activation";
			
			monPanel = new JPanel();
    		Vector ligne = new Vector();
    		Vector enTete = new Vector();
    		enTete.add("Activation");
    		enTete.add("Begin exec");
    		enTete.add("End exec");
    		enTete.add("Deadline");
    		
    		JTable Table = new JTable(ligne,enTete);
    		Table.setRowHeight((int)(Table.getRowHeight()*1.5));
    		JScrollPane scroll = new JScrollPane(Table);
    		Table.setEnabled(false);
    		Table.setDefaultRenderer(Object.class, new MonCellRenderer(1));
    		
    		monPanel.setLayout(new BorderLayout());
    		
    		monPanel.add(scroll, BorderLayout.CENTER);
    		
			/*JPanel*/
		}

		public String getName() {
			return this.label;
		}

		public JPanel getPanel() {
			return this.monPanel;
		}
    	
    }
    /**
     * node DATA
     * @author richard
     *
     */
    private class nData extends DefaultMutableTreeNode implements nInterface{
    	private JPanel monPanel;
    	private String label;
		private Data data;
		public nData(Data next) {
    		super();
    		this.data = next;
    		this.label = data.getSource().getName() + " --> " + data.getDestination().getName();
    		/**
    		 * Panel
    		 */
    		monPanel = new JPanel();
    		Vector ligne = new Vector();
    		Vector enTete = new Vector();

    		enTete.add("Name");
    		enTete.add("Value");
    

    		Vector l1 = new Vector();
    		l1.add("ClassName");
    		l1.add(data.getClass().getName()) ;
    		ligne.add(l1);

    		l1 = new Vector();
    		l1.add("Source");
    		l1.add(data.getSource().getName()) ;
    		ligne.add(l1);
    		
    		 l1 = new Vector();
    		l1.add("Destination");
    		l1.add(data.getDestination().getName()) ;
    		ligne.add(l1);
    		
    		 l1 = new Vector();
    		l1.add("Divisor");
    		l1.add(data.getRate()) ;
    		ligne.add(l1);
    		
    		l1 = new Vector();
    		l1.add("Size");
    		l1.add(data.getSize()) ;
    		ligne.add(l1);
    		
       		Vector V = data.getOwnFileds();
    		Iterator I = V.iterator();
    		while(I.hasNext()){
    			Vector vv = (Vector)I .next() ;
    			ligne.add(vv);
    			
    		}
    		
    		
    		JTable Table = new JTable(ligne,enTete);
    		Table.setRowHeight((int)(Table.getRowHeight()*1.5));
    		JScrollPane scroll = new JScrollPane(Table);
    		Table.setEnabled(false);
    		Table.setDefaultRenderer(Object.class, new MonCellRenderer(1));
    		
    		monPanel.setLayout(new BorderLayout());
    		
    		monPanel.add(scroll, BorderLayout.CENTER);

    		
		
		}

		public String getName() {
		
			return  this.label;
		}
		public JPanel getPanel(){
			return this.monPanel;
		}

    	
    }
    /**
     * Node Processor
     * @author richard
     *
     */
    private class nProcessor extends DefaultMutableTreeNode implements nInterface {
    	public nProcessor(Processor next) {
    		super(next.getName());
    		P=next;
    		
    		/**
    		 * Panel
    		 */
    		monPanel = new JPanel();
    		Vector ligne = new Vector();
    		Vector enTete = new Vector();
    		
    		enTete.add("Name");
    		enTete.add("Value");
    
    		
    		Vector l1 = new Vector();
    		l1.add("ClassName");
    		l1.add(P.getClass().getName()) ;
    		ligne.add(l1);
    		
    		l1 = new Vector();
    		l1.add("Name");
    		l1.add(P.getName()) ;
    		ligne.add(l1);
    		
    		l1 = new Vector();
    		l1.add("ID");
    		l1.add(P.getId()) ;
    		ligne.add(l1);
    		
    		Vector V = this.P.getOwnFileds();
    		Iterator I = V.iterator();
    		while(I.hasNext()){
    			Vector vv = (Vector)I .next() ;
    			ligne.add(vv);
    			
    		}
    		
    		
    		
    		
    		
    		JTable Table = new JTable(ligne,enTete);
    		Table.setRowHeight((int)(Table.getRowHeight()*1.5));
    		JScrollPane scroll = new JScrollPane(Table);
    		Table.setEnabled(false);
    		Table.setDefaultRenderer(Object.class, new MonCellRenderer(1));
    		
    		monPanel.setLayout(new BorderLayout());
    		
    		monPanel.add(scroll, BorderLayout.CENTER);
    		
    		
    		
    		
    		
			
		}

    	/**
    	 * 
    	 * @return
    	 */
		public String getName() {
			return  this.P.getName();
		}
		Processor P;
		private JPanel monPanel;
		public JPanel getPanel(){
			return this.monPanel;
		}

    	
    }
    /**
     * node Task
     * @author richard
     *
     */
    private class nTask extends DefaultMutableTreeNode implements nInterface{
    	public nTask(Task next) {
    		super(next.getName());
    		this.task = next;
    		
    		/**
    		 * Panel
    		 */
    		monPanel = new JPanel();
    		Vector ligne = new Vector();
    		Vector enTete = new Vector();
    		enTete.add("Name");
    		enTete.add("Value");
    

    		Vector l1 = new Vector();
    		l1.add("ClassName");
    		l1.add(task.getClass().getName()) ;
    		ligne.add(l1);
    		l1 = new Vector();
    		l1.add("ID");
    		l1.add(task.getId()) ;
    		ligne.add(l1);

    		l1 = new Vector();
    		l1.add("Name");
    		l1.add(task.getName()) ;
    		ligne.add(l1);

    		l1 = new Vector();
    		l1.add("BCET");
    		l1.add(task.getBCET()) ;
    		ligne.add(l1);

    		l1 = new Vector();
    		l1.add("WCET");
    		l1.add(task.getWCET()) ;
    		ligne.add(l1);

    		l1 = new Vector();
    		l1.add("Deadline");
    		l1.add(task.getDeadline()) ;
    		ligne.add(l1);

    		l1 = new Vector();
    		l1.add("Period");
    		l1.add(task.getPeriod()) ;
    		ligne.add(l1);

    		l1 = new Vector();
    		l1.add("Priority");
    		l1.add(task.getPriority()) ;
    		ligne.add(l1);
    		
    		l1 = new Vector();
    		l1.add("Activation Date");
    		l1.add(task.activationDate) ;
    		ligne.add(l1);
    		

    		l1 = new Vector();
    		l1.add("Power deviation");
    		l1.add(task.getPowerDeviation()) ;
    		ligne.add(l1);
    		
    		l1 = new Vector();
    		l1.add("AET Calc");
    		l1.add(task.calcAET) ;
    		ligne.add(l1);

    		Vector V = this.task.getOwnFileds();
    		Iterator I = V.iterator();
    		while(I.hasNext()){
    			Vector vv = (Vector)I .next() ;
    			ligne.add(vv);
    			
    		}
    		
    		
    		JTable Table = new JTable(ligne,enTete);
    		Table.setRowHeight((int)(Table.getRowHeight()*1.5));
    		JScrollPane scroll = new JScrollPane(Table);
    		Table.setEnabled(false);
    		Table.setDefaultRenderer(Object.class, new MonCellRenderer(1));
    		
    		monPanel.setLayout(new BorderLayout());
    		
    		monPanel.add(scroll, BorderLayout.CENTER);
    		

		}

		public String getName() {

			return  this.task.getName();
		}

		Task task;
		private JPanel monPanel;
		public JPanel getPanel(){
			return this.monPanel;
		}

    }
    /**
     * Node Scheduler
     * @author richard
     *
     */
    private class nScheduler extends DefaultMutableTreeNode implements nInterface{
    	Scheduler sched;
    	JPanel monPanel;
    	public nScheduler(Scheduler scheduler) {
    		super(scheduler.getName());
    		this.sched = scheduler;
    		
    		/**
    		 * Panel
    		 */
    		monPanel = new JPanel();
    		Vector ligne = new Vector();
    		Vector enTete = new Vector();
    		enTete.add("Name");
    		enTete.add("Value");
    
    		Vector l1 = new Vector();
    		l1.add("ClassName");
    		l1.add(sched.getClass().getName()) ;
    		
    		
    		
    		ligne.add(l1);
    		
    		Vector l2 = new Vector();
    		l2.add("overhead (ms)");
    		l2.add(sched.overhead) ;
    		ligne.add(l2);
    		
    		Vector l3= new Vector();
    		l3.add("overhead (slot)");
    		l3.add(sched.getTickOverhead()) ;
    		ligne.add(l3);
    		
    		

    		Vector V = this.sched.getOwnFileds();
    		Iterator I = V.iterator();
    		while(I.hasNext()){
    			Vector vv = (Vector)I .next() ;
    			ligne.add(vv);
    			
    		}
    		
    		
    		JTable Table = new JTable(ligne,enTete);
    		Table.setRowHeight((int)(Table.getRowHeight()*1.5));
    		JScrollPane scroll = new JScrollPane(Table);
    		Table.setEnabled(false);
    		Table.setDefaultRenderer(Object.class, new MonCellRenderer(1));
    		
    		monPanel.setLayout(new BorderLayout());
    		
    		monPanel.add(scroll, BorderLayout.CENTER);
    		
    		

    		
			
		}
/**
 * 
 * @return
 */
		public String getName() {
	
			return this.sched.getName();
			
		}
		/**
		 * 
		 */
		public JPanel getPanel(){
			
			
			return this.monPanel;
		}


    	
    	
    }
    /**
     * 
     * @author richard
     *
     */
    public class MonCellRenderer extends DefaultTableCellRenderer {
    	int limite = 0;
    	public MonCellRenderer(int i) {
    		super();
    		limite = i;
		
		}
    	/**
    	 * 
    	 * 
    	 */
		public Component getTableCellRendererComponent(JTable table, Object value,
    			boolean isSelected, boolean hasFocus, int row, int column) {
    		Component cell = super.getTableCellRendererComponent(table, value,
    				isSelected, hasFocus, row, column);

    		if (row >= limite){
    	
    			
    		}
    			
    		else {
    			
    		}
    		return cell;
    	}
    }
    /**
     * 
     * 
     * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
     */
    
	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub
		this.console.keyPressed(e);
		
	}

	/**
	 * 
	 */
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		this.console.keyReleased(e);
		
	}

	/**
	 * 
	 */
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		this.console.keyTyped(e);
		
	}    
  
    

	
}
